home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / EMBL Search / Sources / locate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-04  |  8.6 KB  |  335 lines  |  [TEXT/KAHL]

  1. /*
  2. *********************************************************************
  3. *    
  4. *    locate.c
  5. *    Locating index directories
  6. *
  7. *    Rainer Fuchs
  8. *    EMBL Data Library
  9. *    Postfach 10.2209
  10. *    D-6900 Heidelberg, FRG
  11. *    E-mail: fuchs@embl-heidelberg.de
  12. *
  13. *    Copyright © 1992 EMBL Data Library
  14. *        
  15. **********************************************************************
  16. *    
  17. */
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21.  
  22. #include "EMBL-Search.h"
  23. #include "EMBL-Search.rsrc.h"
  24.  
  25. /*
  26. ******************************* Prototypes ****************************
  27. */
  28.  
  29. #include "locate.h"
  30. #include "util.h"
  31. #include "window.h"
  32. #include "pstr.h"
  33. #include "cd.h"
  34. #include "getpath.h"
  35. #include "events.h"
  36.  
  37. static void ShortenPath(StringPtr path, DialogPtr myDialog, short item);
  38. static pascal Boolean FoldersOnly(ParmBlkPtr pb);
  39. static pascal short myGetDirHook(short theItem, DialogPtr myDialog);
  40.  
  41.  
  42. /*
  43. ********************************* Globals *****************************
  44. */
  45.  
  46. extern short    gPrefVRefNum;
  47. extern Prefs    gPrefs;
  48. extern VolInfo    gCurrentCD;
  49. extern DBInfo    gDBInfo[DB_NUM];
  50.  
  51. static Boolean    lbCurDirValid, lbCDROM;
  52. static long        lgMyCurDir;
  53. static SFReply    reply;
  54.  
  55.  
  56. /**************************************
  57. *    Preferences: change directory locations
  58. */
  59.  
  60. void Locate()
  61. {
  62.     EventRecord    myEvent;
  63.     DialogPtr    myDialog;
  64.     Str255        EMBLIndexPath,SWISSIndexPath;
  65.     Boolean        bQuit = FALSE,bEMBLchanged = FALSE, bSWISSchanged = FALSE;
  66.     short            itemHit;
  67.     DirSpec        newSpec[DB_NUM];
  68.     OSErr            ret;
  69.     short            i;
  70.     
  71.     CenterDA('DLOG',LOCATE_DLG,66);
  72.     myDialog=GetNewDialog(LOCATE_DLG,NULL,(WindowPtr)-1);
  73.  
  74.     /* show current path to EMBL index directory */
  75.     GetDirPath(&gPrefs.inxDirSpec[DB_EMBL],EMBLIndexPath);
  76.     ShortenPath(EMBLIndexPath,myDialog,LOCATE_EMBLINX_TXT);
  77.     SetDlgText(myDialog,LOCATE_EMBLINX_TXT,EMBLIndexPath);
  78.     
  79.     /* show current path to SWISS index directory */
  80.     GetDirPath(&gPrefs.inxDirSpec[DB_SWISS],SWISSIndexPath);
  81.     ShortenPath(SWISSIndexPath,myDialog,LOCATE_SWISSINX_TXT);
  82.     SetDlgText(myDialog,LOCATE_SWISSINX_TXT,SWISSIndexPath);
  83.  
  84.     /* install user items to draw frame and default button outline */
  85.     InstallUserItem(myDialog,LOCATE_USRITEM1,-1,DrawFrame);
  86.     InstallUserItem(myDialog,LOCATE_USRITEM2,OK,DrawOKBoxRect);
  87.  
  88.     ShowWindow(myDialog);
  89.     while(!bQuit) {    /* display dialog using our standard filter proc */            
  90.         ModalDialog((ProcPtr)myDialogFilter,&itemHit);
  91.         switch(itemHit) {
  92.             case OK:
  93.             case Cancel:
  94.                 bQuit=TRUE;
  95.                 break;
  96.             case LOCATE_EMBLCHG_BTN:
  97.                 /* ask user for new directory location */
  98.                 if(DoGetDirectory(&newSpec[DB_EMBL])) {
  99.                     GetDirPath(&newSpec[DB_EMBL],EMBLIndexPath);
  100.                     ShortenPath(EMBLIndexPath,myDialog,LOCATE_EMBLINX_TXT);
  101.                     SetDlgText(myDialog,LOCATE_EMBLINX_TXT,EMBLIndexPath);
  102.                     bEMBLchanged = TRUE;
  103.                 }
  104.                 break;
  105.             case LOCATE_SWISSCHG_BTN:
  106.                 /* ask user for new directory location */
  107.                 if(DoGetDirectory(&newSpec[DB_SWISS])) {
  108.                     GetDirPath(&newSpec[DB_SWISS],SWISSIndexPath);
  109.                     ShortenPath(SWISSIndexPath,myDialog,LOCATE_SWISSINX_TXT);
  110.                     SetDlgText(myDialog,LOCATE_SWISSINX_TXT,SWISSIndexPath);
  111.                     bSWISSchanged = TRUE;
  112.                 }
  113.                 break;
  114.         }
  115.     }
  116.         
  117.     DisposDialog(myDialog);
  118.     /* if user clicked OK and something has changed we copy new directory
  119.         information to gPrefs */
  120.     if(itemHit == OK && (bEMBLchanged || bSWISSchanged)) {
  121.         if(bEMBLchanged) {
  122.             pstrcpy(gPrefs.inxDirSpec[DB_EMBL].volName, newSpec[DB_EMBL].volName);
  123.             gPrefs.inxDirSpec[DB_EMBL].dirID = newSpec[DB_EMBL].dirID;
  124.         }
  125.         
  126.         if(bSWISSchanged) {
  127.             pstrcpy(gPrefs.inxDirSpec[DB_SWISS].volName, newSpec[DB_SWISS].volName);
  128.             gPrefs.inxDirSpec[DB_SWISS].dirID = newSpec[DB_SWISS].dirID;
  129.         }
  130.         
  131.         /* close old wd's and open new one's */
  132.         ret=CloseWD(gDBInfo[DB_EMBL].SeqWDRefNum);
  133.         ret=CloseWD(gDBInfo[DB_SWISS].SeqWDRefNum);
  134.         ret=CloseWD(gDBInfo[DB_EMBL].InxWDRefNum);
  135.         ret=CloseWD(gDBInfo[DB_SWISS].InxWDRefNum);
  136.         if(!InitDB(gCurrentCD.vRefNum,gCurrentCD.volName)) {
  137.             ErrorMsg(ERR_REINITFAIL);    /* this should never occur */
  138.             for(i=0;i<DB_NUM;++i) {
  139.                 *gPrefs.inxDirSpec[i].volName = EOS;
  140.                 gPrefs.inxDirSpec[i].dirID = 0;
  141.             }
  142.             InitCD();    /* complete restart */
  143.         }
  144.         
  145.         ErrorMsg(ERR_PREFCHGWARN);
  146.     }
  147. }
  148.  
  149. /**************************************
  150. *    Build a complete path from a DirSpec. If volume name is EOS this indicates
  151. *    that CD-ROM should be used (default).
  152. */
  153.  
  154. Boolean GetDirPath(DirSpec *dirSpec,StringPtr path)
  155. {
  156.     Str31 cdStr;
  157.     short vRefNum;
  158.     char    fullPath[256];
  159.     
  160.     GetIndString(cdStr,OTHERS,CDROMPATH);
  161.     pstrcpy(path,cdStr);
  162.  
  163.     if(*dirSpec->volName == EOS) {
  164.         return(TRUE);
  165.     }
  166.     else {
  167.         /* find volume number for a given volume name */
  168.         if(!GetVRefNumFromName(dirSpec->volName,&vRefNum)) {
  169.             return(FALSE);
  170.         }
  171.         else {
  172.             /* get complete path from dir ID and volume name */
  173.             if(!GetPathFromDirID(vRefNum,dirSpec->dirID,
  174.                                     "\p",fullPath)) {
  175.                 return(FALSE);
  176.             }
  177.             else {
  178.                   strcpy((char *)path,fullPath);
  179.                 CtoPstr((char *)path);
  180.                 return(TRUE);
  181.             }
  182.         }
  183.     }
  184. }
  185.  
  186. /**************************************
  187. *    Shorten a complete path to fit into a dialog static text item.
  188. *    We first try the complete path. If it doesn't fit, we take the 
  189. *    volume name, add a '…' character and then as many subfolder names
  190. *    as possible to fit into the given box. We will always show at least
  191. *    two levels of the file system hierarchy, the volume name and the file name
  192. *    or the directory name in case the path points to a directory.
  193. *    This routine works for both, file and directory path specifications.
  194. *    Return value: by side-effect: modified path in "path"
  195. */
  196.  
  197. static void ShortenPath(StringPtr path, DialogPtr myDialog, short item)
  198. {
  199.     short        kind;
  200.     Handle    h;
  201.     Rect        r;
  202.     short        boxWidth;
  203.     GrafPtr    savePort;
  204.     Str255    newPath;
  205.     char        topFolder[256], *p;
  206.     short        depth,maxDepth;
  207.     short        i;
  208.     
  209.     savePort = ChangePort(myDialog);
  210.     
  211.     GetDItem(myDialog,item,&kind,&h,&r);
  212.     boxWidth = r.right - r.left;
  213.         
  214.     PtoCstr(path);
  215.     strcpy((char *)newPath,(char *)path);
  216.     /* for each directory/volume in path increase depth counter */
  217.     for(p=(char *)newPath,maxDepth=0;*p;++p) {    
  218.         if(*p == ':')
  219.             ++maxDepth;
  220.     }
  221.     /* if last element in path is filename, add one level of depth */
  222.     if(*(p-1) != ':')             
  223.         ++maxDepth;
  224.         
  225.     /* we will keep at least two levels in the path, therefore we need to do
  226.         any modifications only if maxDepth is greater than 2 */
  227.     if(maxDepth > 2) {
  228.         strcpy(topFolder,(char *)newPath);
  229.         for(p=topFolder;*p != ':';++p)
  230.             ;
  231.         *p = EOS;
  232.         strcat(topFolder,":…:");
  233.     }
  234.         
  235.     CtoPstr((char *)newPath);
  236.     for(depth=2;depth < maxDepth && StringWidth(newPath) > boxWidth;++depth) {
  237.         strcpy((char *)newPath,topFolder);
  238.         for(p=(char *)path,i=0;i<depth;++p) {
  239.             if(*p == ':')
  240.                 ++i;
  241.         }
  242.         strcat((char *)newPath,p);
  243.         CtoPstr((char *)newPath);
  244.     }
  245.     
  246.     pstrcpy(path,newPath);
  247.     SetPort(savePort);
  248. }
  249.  
  250. /**************************************
  251. *    Get new directory from user. We use a modified SFGetFile dialog,
  252. *    modelled on Apple DTS SC.18. User can also choose "CD-ROM".
  253. *    Return values:    TRUE, if user selected a directory
  254. *                        FALSE; if user cancelled
  255. */
  256.  
  257. Boolean DoGetDirectory(DirSpec *dirSpec)
  258. {
  259.     Str31 str;
  260.     Point where;
  261.     
  262.     /* Deactivate current front window. SFPut/GetFile sends an activate event
  263.         when it quits but not when it opens ! */
  264.     HandleActivates(FrontWindow(),0);
  265.     CenterSFDlg(DIRSELECT_DLG,&where);
  266.     SFPGetFile(where,"\p",(ProcPtr)FoldersOnly,-1,NULL,
  267.                 (ProcPtr)myGetDirHook,&reply,DIRSELECT_DLG,NULL);
  268.                     
  269.     if(lbCurDirValid) {    /* lbCurDirValid is TRUE, if user selected a directory */
  270.         if(lbCDROM) {        /* lbCDROM is TRUE, if user selected CDROM */
  271.             *dirSpec->volName = EOS;    
  272.             dirSpec->dirID = 0;
  273.         }
  274.         else {
  275.             /* Pick up volume vRefNum from LoMem variable and find volume name */
  276.             if(!GetNameFromVRefNum(str,-SFSaveDisk))
  277.                 return(FALSE);
  278.             else {
  279.                 pstrcpy(dirSpec->volName,str);
  280.                 dirSpec->dirID = lgMyCurDir;
  281.             }
  282.         }
  283.         
  284.         return(TRUE);
  285.     }
  286.     else return(FALSE);
  287. }
  288.  
  289. /**************************************
  290. *    Make sure we show only folders in the SFDialog list
  291. */
  292.  
  293. static pascal Boolean FoldersOnly(ParmBlkPtr pb)
  294. {
  295.     return((pb->fileParam.ioFlAttrib & 0x10) == 0);
  296. }
  297.  
  298. /**************************************
  299. *    Our hook routine to handle the non-standard buttons
  300. */
  301.  
  302. static pascal short myGetDirHook(short theItem, DialogPtr myDialog)
  303. {
  304. #define getDirButton 11
  305. #define getDirNowButton 12
  306. #define getCDButton 13
  307.  
  308.     switch(theItem) {
  309.         /* initialisation of dialog
  310.             (called first time before dialog is displayed) */
  311.         case -1:
  312.             lbCurDirValid = FALSE;
  313.             lbCDROM = FALSE;
  314.             break;
  315.         case getDirButton:
  316.             if(reply.fType != 0) {
  317.                 lgMyCurDir = reply.fType;
  318.                 lbCurDirValid = TRUE;
  319.                 theItem = getCancel;
  320.             }
  321.             break;
  322.         case getDirNowButton:
  323.             lgMyCurDir = CurDirStore; /* get dirID from LoMem variable */
  324.             lbCurDirValid = TRUE;
  325.             theItem = getCancel;
  326.             break;
  327.         case getCDButton:
  328.             lbCDROM = TRUE;
  329.             lbCurDirValid = TRUE;
  330.             theItem = getCancel;
  331.             break;
  332.     }
  333.     
  334.     return(theItem);
  335. }